package com.cnsugar.common.jdbc;

import org.springframework.jdbc.core.PreparedStatementCreator;

import java.sql.*;
import java.text.SimpleDateFormat;

/**
 * PreparedStatementCreator实现
 * @Author Sugar
 * @Version 2018/6/4 17:51
 */
public class PreparedStatementCreatorImpl implements PreparedStatementCreator {
    private String sql;
    private Object[] values;
    private int[] types;
    private String pkName;

    public PreparedStatementCreatorImpl(String sql, Object[] values, int[] types) {
        this.sql = sql;
        this.values = values;
        this.types = types;
    }

    public PreparedStatementCreatorImpl(String sql, Object[] values, int[] types, String pkName) {
        this(sql, values, types);
        this.pkName = pkName;
    }

    public PreparedStatement createPreparedStatement(Connection conn) throws SQLException {
        PreparedStatement ps = (pkName == null ? conn.prepareStatement(sql) : conn.prepareStatement(sql, new String[]{pkName}));
        setValues(ps, values, types);
        return ps;
    }

    public static void setValues(PreparedStatement ps, Object[] values, int[] types) throws SQLException {
        if (types == null) {
            for (int i = 0; i < values.length; i++) {
                if (values[i] == null) {
                    ps.setObject(i + 1, null);
                    continue;
                }
                if (values[i] instanceof java.util.Date) {
                    ps.setDate(i + 1, new Date(((java.util.Date) values[i]).getTime()));
                } else {
                    ps.setObject(i + 1, values[i]);
                }
            }
        } else {
            for (int i = 0; i < values.length; i++) {
                if (values[i] == null) {
                    ps.setNull(i + 1, types[i]);
                    continue;
                }
                switch (types[i]) {
                    case Types.VARCHAR:
                        ps.setString(i + 1, values[i].toString());
                        break;
                    case Types.INTEGER:
                        ps.setInt(i + 1, Integer.valueOf(values[i].toString()));
                        break;
                    case Types.BIGINT:
                        ps.setLong(i + 1, Long.valueOf(values[i].toString()));
                        break;
                    case Types.FLOAT:
                        ps.setFloat(i + 1, Float.valueOf(values[i].toString()));
                        break;
                    case Types.TIMESTAMP:
                        ps.setTimestamp(i + 1, Timestamp.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.sss").format(values[i])));
                        break;
                    case Types.DECIMAL:
                    case Types.DOUBLE:
                        ps.setDouble(i + 1, Double.valueOf(values[i].toString()));
                        break;
                    case Types.BLOB:
                        ps.setBytes(i + 1, (byte[]) values[i]);
                        break;
                    case Types.SMALLINT:
                        ps.setShort(i + 1, (short) values[i]);
                        break;
                    case Types.DATE:
                        ps.setDate(i + 1, Date.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(values[i])));
                        break;
                    default:
                        ps.setObject(i + 1, values[i]);
                        break;
                }
            }
        }
    }
}
